package com.hk.service.business;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.hk.domain.entity.Employee;
import com.hk.exception.BizException;
import com.hk.utils.R;
import jodd.util.Base64;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author: dpb
 * @date: 2022/11/30
 */
@Service
@Slf4j
public class ImportOrExportFileBusiness {

    ExecutorService executorService = Executors.newFixedThreadPool(10);


    public R importFileCountDownSync(MultipartFile file) throws IOException, InterruptedException {

        if (checkParamer(file)) return R.error("文件格式不正确！");

//        ExecutorService executorService = Executors.newFixedThreadPool(10);
        CountDownLatch countDownLatch = new CountDownLatch(2);

        long start = System.currentTimeMillis();
        Future<List<Employee>> fb1 = executorService.submit(() -> {
            try {
                List<Employee> list = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list.isEmpty()) {
                    return list;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
            return Collections.emptyList();
        });

        Future<List<Employee>> fb2 = executorService.submit(() -> {
            try {
                List<Employee> list2 = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list2.isEmpty()) {
                    return list2;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
            return Collections.emptyList();
        });
        Future<List<Employee>> fb3 = executorService.submit(() -> {
            try {
                List<Employee> list3 = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list3.isEmpty()) {
                    return list3;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
            return Collections.emptyList();
        });

        Future<List<Employee>> fb4 = executorService.submit(() -> {
            try {
                List<Employee> list = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list.isEmpty()) {
                    return list;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
            return Collections.emptyList();
        });
        Future<List<Employee>> fb5 = executorService.submit(() -> {
            try {
                List<Employee> list = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list.isEmpty()) {
                    return list;
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
            return Collections.emptyList();
        });

        countDownLatch.await();
        long time = System.currentTimeMillis() - start;
        return R.ok().put("time", String.valueOf(time));
    }

    public R importFileFutureSync(MultipartFile file) throws Exception {

        if (checkParamer(file)) return R.error("文件格式不正确！");

        long start = System.currentTimeMillis();
        //CompletableFuture.runAsync 创建无任务的异步操作
        CompletableFuture<List<Employee>> list1 = CompletableFuture.supplyAsync(() -> {
            try {
                List<Employee> list = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list.isEmpty()) {
                    return list;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Collections.emptyList();
        }, executorService);

        CompletableFuture<List<Employee>> list2 = CompletableFuture.supplyAsync(() -> {
            try {
                List<Employee> list = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list.isEmpty()) {
                    return list;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Collections.emptyList();
        }, executorService);

        CompletableFuture<List<Employee>> list3 = CompletableFuture.supplyAsync(() -> {
            try {
                List<Employee> list = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list.isEmpty()) {
                    return list;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Collections.emptyList();
        }, executorService);

        CompletableFuture<List<Employee>> list4 = CompletableFuture.supplyAsync(() -> {
            try {
                List<Employee> list = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list.isEmpty()) {
                    return list;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Collections.emptyList();
        }, executorService);

        CompletableFuture<List<Employee>> list5 = CompletableFuture.supplyAsync(() -> {
            try {
                List<Employee> list = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
                if (!list.isEmpty()) {
                    return list;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return Collections.emptyList();
        }, executorService);

        CompletableFuture.allOf(list1, list2, list3, list4, list5);

        log.info("list1:{}", JSON.toJSONString(list1.get()));
        log.info("list2:{}", JSON.toJSONString(list2.get()));
        log.info("list3:{}", JSON.toJSONString(list3.get()));
        log.info("list4:{}", JSON.toJSONString(list4.get()));
        log.info("list5:{}", JSON.toJSONString(list5.get()));

        long time = System.currentTimeMillis() - start;
        return R.ok().put("time", String.valueOf(time));
    }

    private boolean checkParamer(MultipartFile file) {
        String filename = file.getOriginalFilename();

        if (!filename.endsWith(".xlsx") && !filename.endsWith(".xls")) {
            log.error("文件格式不正确！当前的文件格式：{}", filename);
            return true;
        }
        return false;
    }


    public R importFile(MultipartFile file) throws Exception{
        if (checkParamer(file)) return R.error("文件格式不正确！");
        long start = System.currentTimeMillis();
        List<Employee> list1 = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
        List<Employee> list2 = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
        List<Employee> list3 = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
        List<Employee> list4 = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
        List<Employee> list5 = EasyExcel.read(file.getInputStream()).head(Employee.class).sheet("附表一").doReadSync();
        log.info("list1:{}", JSON.toJSONString(list1));
        log.info("list2:{}", JSON.toJSONString(list2));
        log.info("list3:{}", JSON.toJSONString(list3));
        log.info("list4:{}", JSON.toJSONString(list4));
        log.info("list5:{}", JSON.toJSONString(list5));
        long time = System.currentTimeMillis() - start;
        return R.ok().put("time", String.valueOf(time));
    }


    public void exportFile(HttpServletResponse response) throws IOException {
        List<Employee> list = new ArrayList<>();
        List<Employee> list2 = new ArrayList<>();
        list.add(new Employee("zs","CEO","12"));
        list.add(new Employee("zs","CEO","12"));
        list.add(new Employee("zs","CEO","12"));
        list.add(new Employee("zs","CEO","12"));
        list.add(new Employee("zs","CEO","12"));
        list.add(new Employee("zs","CEO","12"));


        //设置样式，内容样式策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //垂直居中，水平居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        //设置自动换行
        contentWriteCellStyle.setWrapped(false);
        //字体策略
        WriteFont contentWriteFont = new WriteFont();
        //字体大小
        contentWriteFont.setFontHeightInPoints((short) 12);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        //头策略使用默认
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");

        String fileName = "测试";
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");



//        response.setContentType("application/vnd.ms-excel");
//        response.setCharacterEncoding("utf-8");
//        fileName = URLEncoder.encode(fileName, "UTF-8");
//        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        ServletOutputStream outputStream = response.getOutputStream();
        String flag =  "1";

//        int count = 0;
//        EasyExcel.write(response.getOutputStream(), Employee.class).sheet("员工信息").doWrite(list);

        //一个excel文件导出多个sheet页
        try {
            ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
            WriteSheet writeSheet = EasyExcel.writerSheet(0, "附表一").head(Employee.class).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle)).build();
            excelWriter.write(list, writeSheet);
//            count++;
//            switch (flag) {
//                case "1":
                    writeSheet = EasyExcel.writerSheet(3, "附表二").head(Employee.class).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle)).build();
                    if (!list2.isEmpty()) {
                        excelWriter.write(list2, writeSheet);
                    }
//                    break;
//                case "2":
                    writeSheet = EasyExcel.writerSheet(8, "附表三").head(Employee.class).registerWriteHandler(new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle)).build();
                    excelWriter.write(list, writeSheet);
//                    break;
//            }
            excelWriter.finish();
        } catch (Exception e) {
            log.error("文件导出失败，原因：{}", e.getMessage());
            throw new BizException("文件导出失败");
        }

    }


    public static void test(HttpServletResponse response,String fileName){

    }


}
